package handler

import (
	"encoding/json"
	"fmt"
	"log"
	"sync"

	"goEmqxToDb/config"
	"goEmqxToDb/database"
	"goEmqxToDb/mqtt"

	MQTT "github.com/eclipse/paho.mqtt.golang"
)

// MessageHandler 消息处理器
type MessageHandler struct {
	mqttClient    *mqtt.Client
	dbClients     map[int]*database.MySQLClient
	dbClientsLock sync.RWMutex
}

// NewMessageHandler 创建新的消息处理器
func NewMessageHandler(mqttClient *mqtt.Client) *MessageHandler {
	return &MessageHandler{
		mqttClient: mqttClient,
		dbClients:  make(map[int]*database.MySQLClient),
	}
}

// HandleMessage 处理MQTT消息
func (h *MessageHandler) HandleMessage(client MQTT.Client, msg MQTT.Message) {
	log.Printf("处理消息: %s", msg.Topic())

	// 解析主题
	projectIdentifier, groupIdentifier, err := mqtt.ParseTopic(msg.Topic())
	if err != nil {
		log.Printf("解析主题失败: %v", err)
		return
	}

	log.Printf("项目标识: %s, 组标识: %s", projectIdentifier, groupIdentifier)

	// 解析JSON数据
	var data map[string]interface{}
	err = json.Unmarshal(msg.Payload(), &data)
	if err != nil {
		log.Printf("解析JSON数据失败: %v", err)
		return
	}

	// 查找对应的任务配置
	task := h.findTaskByProjectAndGroup(projectIdentifier, groupIdentifier)
	if task == nil {
		log.Printf("未找到对应的任务配置: project=%s, group=%s", projectIdentifier, groupIdentifier)
		return
	}

	// 获取或创建数据库客户端
	dbClient, err := h.getOrCreateDBClient(*task)
	if err != nil {
		log.Printf("获取数据库客户端失败: %v", err)
		return
	}

	// 插入数据到数据库
	err = dbClient.InsertData(groupIdentifier, data)
	if err != nil {
		log.Printf("插入数据失败: %v", err)
		return
	}

	log.Printf("成功处理消息并保存到数据库")
}

// findTaskByProjectAndGroup 根据项目标识和组标识查找任务
func (h *MessageHandler) findTaskByProjectAndGroup(projectIdentifier, groupIdentifier string) *config.Task {
	tasks := h.mqttClient.GetTasks()

	for _, task := range tasks {
		if task.ProjectIdentifier == projectIdentifier {
			for _, groupID := range task.GroupIdentifier {
				if groupID == groupIdentifier {
					return &task
				}
			}
		}
	}

	return nil
}

// getOrCreateDBClient 获取或创建数据库客户端
func (h *MessageHandler) getOrCreateDBClient(task config.Task) (*database.MySQLClient, error) {
	// 添加调试信息
	log.Printf("获取数据库客户端，任务配置:")
	log.Printf("  任务编号: %d", task.TaskNum)
	log.Printf("  任务名称: %s", task.TaskName)
	log.Printf("  数据库主机: %s", task.Host)
	log.Printf("  数据库端口: %d", task.Port)
	log.Printf("  数据库名称: %s", task.Database)
	log.Printf("  数据库用户名: %s", task.Username)

	h.dbClientsLock.RLock()
	if client, exists := h.dbClients[task.TaskNum]; exists {
		h.dbClientsLock.RUnlock()
		return client, nil
	}
	h.dbClientsLock.RUnlock()

	// 创建新的数据库客户端
	h.dbClientsLock.Lock()
	defer h.dbClientsLock.Unlock()

	// 再次检查，防止并发创建
	if client, exists := h.dbClients[task.TaskNum]; exists {
		return client, nil
	}

	client, err := database.NewMySQLClient(task)
	if err != nil {
		return nil, fmt.Errorf("创建MySQL客户端失败: %v", err)
	}

	h.dbClients[task.TaskNum] = client
	return client, nil
}

// Close 关闭所有数据库连接
func (h *MessageHandler) Close() {
	h.dbClientsLock.Lock()
	defer h.dbClientsLock.Unlock()

	for taskNum, client := range h.dbClients {
		if err := client.Close(); err != nil {
			log.Printf("关闭数据库连接失败 (Task %d): %v", taskNum, err)
		}
	}
}
